#include "SharedLib.hpp"

// Window
#if _WIN32
void* loadLib(const char* file) {
	void* handle = (void*)LoadLibrary(file);
	if (handle == nullptr) {
		LOG(InfoLevel::Error, "Failed to load the DLL : ", file);
	}
	return handle;
}

void* loadFunc(void* handle, const char* name) {
	void* func = (void*)GetProcAddress((HMODULE)handle, name);
	if (func == nullptr) {
		LOG(InfoLevel::Error, "Failed to load the function : ", name);
	}
	return func;
}

bool freeLib(void* handle) {
	if (handle != nullptr) {
		if (FreeLibrary((HMODULE)handle) == 0) {
			return false;
		}
	}
	return true;
}
// Unix like
#else
void* loadLib(const char* file) {
	void* handle = dlopen(file, RTLD_NOW | RTLD_LOCAL);
	if (handle == nullptr) {
		LOG(InfoLevel::Error, "Failed to load the DLL : ", file);
	}
	return handle;
}

void* loadFunc(void* handle, const char* name) {
	void* func = dlsym(handle, name);
	if (func == nullptr) {
		// Insert an underscore because certain platform need one
		func = dlsym(handle, '_' + name);
		if (func == nullptr) {
			LOG(InfoLevel::Error, "Failed to load the function : ", name);
		}
	}
	return func;
}

bool freeLib(void* handle) {
	if (handle != nullptr) {
		if (dlclose(handle) != 0)
		{
			return false;
		}
	}
	return true;
}
#endif
